package com.zoe.onelink.auth.component;

import cn.hutool.core.util.ReUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.zoe.onelink.auth.annotation.InnerUrl;
import com.zoe.onelink.auth.properties.AuthProperties;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.Map;
import java.util.Optional;
import java.util.regex.Pattern;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2018</p>
 * <p>公司: 智业软件</p>
 *
 * @author LinHongKai
 * @date 2022-04-25 11:44
 */
@RequiredArgsConstructor
public class InnerUrlServices implements InitializingBean {

    private final AuthProperties authProperties;

    private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");

    @Override
    public void afterPropertiesSet() {
        RequestMappingHandlerMapping mapping = SpringUtil.getBean(RequestMappingHandlerMapping.class);
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();

        map.keySet().forEach(info -> {
            HandlerMethod handlerMethod = map.get(info);

            // 获取方法上边的注解 替代path variable 为 *
            InnerUrl method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), InnerUrl.class);
            Optional.ofNullable(method).ifPresent(inner -> info.getPatternsCondition().getPatterns()
                    .forEach(url -> authProperties.getIgnoreUrls().add(ReUtil.replaceAll(url, PATTERN, "*"))));

            // 获取类上边的注解, 替代path variable 为 *
            InnerUrl controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), InnerUrl.class);
            Optional.ofNullable(controller).ifPresent(inner -> info.getPatternsCondition().getPatterns()
                    .forEach(url -> authProperties.getIgnoreUrls().add(ReUtil.replaceAll(url, PATTERN, "*"))));
        });
    }
}